package br.edu.unifei.cct720.alieninvasion.resources;

import java.io.IOException;
import java.net.URL;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

import br.edu.unifei.cct720.alieninvasion.utils.Messages;

/**
 * This enum encapsulates all the sound effects of a game, so as to separate the sound playing
 * codes from the game codes.
 * 1. Define all your sound effect names and the associated wave file.
 * 2. To play a specific sound, simply invoke SoundEffect.SOUND_NAME.play().
 * 3. You might optionally invoke the static method SoundEffect.init() to pre-load all the
 *    sound files, so that the play is not paused while loading the file for the first time.
 * 4. You can use the static variable SoundEffect.volume to mute the sound.
 */
public enum SoundEffect {

	ALIEN_EXPLODE("explosion.wav"),   
	ALIEN_SHOT("alienshot.wav"),   
	PLAYER_SHOT("shipshot.wav");
	
	/**
	 * Nested class for specifying volume
	 */
	public static enum Volume {
		MUTE,
		LOW, 
		MEDIUM, 
		HIGH
	}

	/** The Clip execution volume */
	public static Volume volume = Volume.LOW;

	/**
	 * Each sound effect has its own clip, loaded with its own sound file
	 */
	private Clip clip;

	/**
	 * Enum Constructor
	 * Create a new sound effect to each element of the enum, with its
	 * own specified sound file
	 * 
	 * @param soundFileName The sound sample reference
	 */
	SoundEffect(String soundFileName) {

		try {
			// Use URL (instead of File) to read from disk and JAR.
			URL url = this.getClass().getClassLoader().getResource(soundFileName);

			// Set up an audio input stream piped from the sound file.
			AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);

			// Get a clip resource.
			clip = AudioSystem.getClip();

			// Open audio clip and load samples from the audio input stream.
			clip.open(audioInputStream);

		} catch (UnsupportedAudioFileException e) {
			e.printStackTrace();
			Messages.showFailure(null, e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			Messages.showFailure(null, e.getMessage());
		} catch (LineUnavailableException e) {
			e.printStackTrace();
			Messages.showFailure(null, e.getMessage());
		}
	}

	/**
	 * Method responsible for play or replay
	 * the sound effect from the beggining.
	 * 
	 */
	public void play() {
		// Check if sound effects volume is un-mute
		if (volume != Volume.MUTE) {
			// Stop the player to prevent it still running
			if (clip.isRunning())
				clip.stop();   
			// rewind to the beginning
			clip.setFramePosition(0); 

			// Start a new playing execution
			clip.start();     
		}
	}
	
	public void stop() {
		clip.stop();
	}

	/**
	 * Static method responsible for pre-load all sound samples.
	 * 
	 */
	public static void init() {
		// calls the constructor for all the elements
		values(); 
	}

	/**
	 * 
	 * @return
	 */
	public static Volume getVolume() {
		return volume;
	}
}